//
//  LcCellData.m
//  18Birdies
//
//  Created by Lc on 15/4/2.
//  Copyright (c) 2015年 Lc. All rights reserved.
//

#import "LcCell.h"
#import "LcCellData.h"
#import "LcFont.h"
#import "LcPreconditions.h"
#import "UIColor+Lc.h"

@interface LcCellData ()
@property(nonatomic, assign) BOOL superCalled;
@end

@implementation LcCellData

static NSMutableDictionary* prototypeCells;

+ (void)initialize {
  if (self == [LcCellData self]) {
    prototypeCells = [NSMutableDictionary dictionary];
  }
}

- (Class)cellClazz {
  NSString* className = NSStringFromClass(self.class);
  if ([className rangeOfString:@"CellData"].length != 0) {
    className = [className stringByReplacingOccurrencesOfString:@"CellData"
                                                     withString:@"Cell"];
    return NSClassFromString(className);
  } else {
    LC_FAIL();
    return nil;
  }
}

- (BOOL)singleton {
  return NO;
}

- (NSString*)nibName {
  return NSStringFromClass(self.cellClazz);
}

- (instancetype)init {
  self = [super init];
  if (self != nil) {
    self.userInfo = [NSMutableDictionary dictionary];
    self.canHide = YES;
  }
  return self;
}

- (id)objectForKeyedSubscript:(id)key {
  return self.userInfo[key];
}

- (void)setObject:(id)object forKeyedSubscript:(nonnull id<NSCopying>)key {
  self.userInfo[key] = object;
}

- (void)refreshCell:(__kindof LcCell*)cell {
  self.superCalled = YES;
  cell.cellData = self;
  cell.contentView.userInteractionEnabled = !self.userInteractionDisabled;
  cell.contentView.alpha = 1 - self.transparency;

  // fix iOS 10 system bug
  cell.clipsToBounds = self.hidden;
}

- (void)willDisplayCell:(__kindof LcCell*)cell {
}

- (void)didDismissCell:(__kindof LcCell*)cell {
}

- (void)postRefreshCell:(LcCell*)cell {
  cell.selectedBackgroundView.frame =
      CGRectMake(0, -1, cell.bounds.size.width, cell.bounds.size.height + 2);
  cell.hidden = cell.cellData.hidden;
}

- (NSString*)reuseId {
  return NSStringFromClass(self.cellClazz);
}

- (id)prototypeCell {
  NSString* cellClazzName = [self reuseId];
  LcCell* cell = prototypeCells[cellClazzName];
  if (cell == nil) {
    cell = [self internalNewCell];
    prototypeCells[cellClazzName] = cell;
  } else {
    self.superCalled = NO;
    [self refreshCell:cell];
    LC_CHECK_TRUE(self.superCalled);
    [self postRefreshCell:cell];
  }
  return cell;
}

- (id)newCell {
  if (self.singleton) {
    return [self prototypeCell];
  } else {
    return [self internalNewCell];
  }
}

- (id)internalNewCell {
  LcCell* cell = nil;
  NSString* reuseId = self.reuseId;
  if (self.nibName == nil) {
    cell = [[[self cellClazz] alloc] initWithStyle:UITableViewCellStyleDefault
                                   reuseIdentifier:reuseId];
  } else {
    cell =
        [[NSBundle mainBundle] loadNibNamed:self.nibName owner:nil
                                    options:nil][0];
    if (cell.reuseIdentifier == nil) {
      [cell setValue:reuseId forKey:@"reuseIdentifier"];
    }
    LC_CHECK_TRUE([cell isMemberOfClass:self.cellClazz]);
  }
  LC_CHECK_NOT_NULL(cell);
  [cell setValue:@NO forKey:@"superCalled"];
  [cell postContruct];
  LC_CHECK_TRUE([[cell valueForKey:@"superCalled"] boolValue]);
  self.superCalled = NO;
  [self refreshCell:cell];
  LC_CHECK_TRUE(self.superCalled);
  [self postRefreshCell:cell];
  return cell;
}

- (CGFloat)cellHeight {
  if (self.hidden) {
    return 0;
  }
  if (_cellHeight == 0) {
    _cellHeight = [(LcCell*)self.prototypeCell height];
  }
  return _cellHeight;
}

- (void)setNeedRefreshCellHeight {
  _cellHeight = 0;
}

- (CGFloat)peekCellHeight {
  if (self.hidden) {
    return 0;
  }
  return _cellHeight;
}

- (void)setHidden:(BOOL)hidden {
  if (hidden) {
    LC_CHECK_TRUE(self.canHide);
  }
  self->_hidden = hidden;
}

@end

